package handlers

import (
	"encoding/json"
	"final-url/entity"
	"final-url/pkg/final"
	"final-url/pkg/final/task"
	"fmt"
	"net/http"
	"time"
)

const (
	convertTypeMT     = "mt"
	convertTypeAlipay = "alipay"
)

func Convert(w http.ResponseWriter, r *http.Request) {
	config := r.Context().Value("config").(*entity.Config)
	start := time.Now()
	defer func() {
		config.Debug(fmt.Sprintf("handler: Convert[%s], cost: %v", r.RequestURI, time.Since(start).Seconds()))
	}()

	if !(r.Method == "POST" && r.Header.Get("Content-Type") == "application/json") {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	var request struct {
		Type string   `json:"type"`
		Urls []string `json:"urls"`
	}
	err := json.NewDecoder(r.Body).Decode(&request)
	if err != nil {
		panic(err)
	}

	var worker *final.Worker
	switch request.Type {
	case convertTypeMT:
		worker = config.MT.Pool.Get(r.Context())
		worker.Submit(task.NewMTs(request.Urls...)...)
		defer config.MT.Pool.Release(r.Context(), worker)
	case convertTypeAlipay:
		worker = config.Alipay.Pool.Get(r.Context())
		worker.Submit(task.NewAlipays(request.Urls...)...)
		defer config.Alipay.Pool.Release(r.Context(), worker)
	default:
		http.Error(w, "request.type not allowed", http.StatusMethodNotAllowed)
		return
	}

	total := len(request.Urls)
	data := make([]map[string]interface{}, 0, total)
	i := 0
	for result := range worker.Results() {
		i++
		item := map[string]interface{}{
			"url": result.Source,
		}
		if result.Err != nil {
			item["err"] = result.Err.Error()
		} else {
			item["success"] = result.Data
		}
		data = append(data, item)
		if i >= total {
			break
		}
	}

	json.NewEncoder(w).Encode(map[string]interface{}{"success": true, "data": data})
}
